home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / mcomm / unixdos.asm < prev    next >
Assembly Source File  |  1994-10-02  |  7KB  |  184 lines

  1.  
  2. title DOS / UNIX FILE TIME CONVERSIONS
  3. page 75,132
  4.  
  5. ; (c) 1991, Mike Dumdei, 6 Holly Lane, Texarkana TX  75503
  6.  
  7. comment |======================================================================
  8.  
  9. unsigned long UnixToDos(unsigned *DosTime, unsigned *DosDate,
  10.         unsigned long UnixTime);
  11.  Converts Unix file time (secs since 1-1-70 GMT) to DOS file time. The
  12.  result is stored in the variables pointed to by DosTime and DosDate and
  13.  also returned as a long in the form DosDate:DosTime.
  14.  
  15. unsigned long DosToUnix(unsigned DosTime, unsigned DosDate);
  16.  Converts Dos file time to Unix file time.  The return value of the
  17.  function is the Unix time.
  18.  
  19. This function does not take into account the difference between the local
  20. time zone and GMT.  Both MSC and TC have a 'timezone' variable that may
  21. be used to adjust the UNIX time values.  MSC defaults to 28800 or +8 hours
  22. (PST) and TC defaults to 18000 or +5 hours (EST).  Zortech C does not have
  23. a timezone variable but functions in it such as 'stat' and 'fstat' that
  24. would normally use 'timezone' have a hard coded value of 25200 or +7 hours
  25. (MST).  There is no 'right' value -- it depends on which time zone you are
  26. in and whether or not DST is in effect.  If an adjustment to local time is
  27. desired, adjust by the number of minutes local time differs from GMT.
  28.  
  29. ==============================================================================|
  30. IFDEF ??version                 ;if TASM
  31.         MASM51
  32.         QUIRKS
  33. ENDIF
  34.  
  35. IFNDEF model
  36.         .MODEL  small, C
  37. ELSE
  38.  %      .MODEL  model, C
  39. ENDIF
  40.         INCLUDE casm.inc
  41.  
  42. HICONST EQU     12ceh
  43. LOCONST EQU     0a600h          ;secs between 1-1-70 GMT & 1-1-80 GMT
  44.  
  45.         .DATA
  46.  
  47. DtoUtbl         DW      0,31,59,90,120,151,181,212,243,273,304,334
  48. UtoDtbl         DB      0,31,28,31,30,31,30,31,31,30,31,30,31
  49.  
  50.         .CODE
  51.  
  52. UnixToDos PROC, DosTime:PTR, DosDate:PTR, UnixTime:WORD;s = 2 words
  53.         mov     ax,UnixTime
  54.         mov     dx,UnixTime[2]  ;DX:AX = secs since 1-1-70 GMT
  55.         sub     ax,LOCONST
  56.         sbb     dx,HICONST      ;DX:AX = secs since 1-1-80 GMT
  57.         jnc     @F              ;jmp if a valid DOS date
  58.         xor     ax,ax
  59.         mov     dx,ax           ;use 1-1-80 localtime if bad date
  60. @@:     shr     dx,1
  61.         rcr     ax,1            ;DX:AX = (secs since 1-1-80) / 2
  62.         mov     bx,43200        ;BX = secs in a day / 2
  63.         div     bx              ;AX = days, DX = secs / 2 remaining
  64.         push    dx              ;save (partial day secs / 2)
  65.         xor     dx,dx
  66.         mov     bx,1461         ;BX = days in 4 year span
  67.         div     bx              ;AX = 4 year spans, DX = excess days
  68.         mov     bx,OFST UtoDtbl ;BX = pointer to days in months array
  69.         shl     ax,1
  70.         shl     ax,1            ;AX = years in complete 4 year spans
  71.         inc     dx              ;days 1 based rather than 0 based
  72.         mov     cx,366
  73.         sub     dx,cx           ;sub days in first year (leap year)
  74.         ja      @F              ;jmp if not a leap year
  75.         mov     BPTR [bx+2],29  ;Feb has 29 days if leap year
  76.         jmp s   calc_month
  77.         mov     BPTR [bx+2],28  ;Feb has 28 days in not a leap year
  78. @@:     dec     cx
  79. @@:     inc     ax              ;add another year to years since 1980
  80.         sub     dx,cx           ;sub days in a year
  81.         ja      @B              ;loop till get to current year
  82. calc_month:
  83.         add     dx,cx           ;subtracted once too many, add back
  84.         xchg    ax,dx           ;AX=days this year, DX=yrs since 1980
  85. @@:     inc     bx
  86.         sub     al,[bx]
  87.         sbb     ah,dh
  88.         or      ax,ax
  89.         jg      @B              ;sub days till get to current month
  90.         add     al,[bx]         ;AL = current day
  91.         sub     bx,OFST UtoDtbl ;BX = current month
  92.         mov     dh,dl
  93.         shl     dh,1            ;DX bits 9-15 = year
  94.         mov     dl,al           ;DX bits 0-4 = day
  95.         mov     cl,5
  96.         shl     bx,cl
  97.         or      dx,bx           ;DX bits 5-8 = month
  98.         pop     ax              ;AX = partial day secs / 2
  99.         push    dx              ;save completed month,day,year
  100.         xor     dx,dx
  101.         mov     bx,1800
  102.         div     bx              ;AX = hours, DX = mins,secs / 2
  103.         mov     cl,3
  104.         shl     al,cl
  105.         mov     bh,al           ;BH bits 11-15 = hour
  106.         mov     ax,dx
  107.         mov     bl,30
  108.         div     bl              ;AL = mins, AH = secs / 2
  109.         mov     bl,ah           ;BL bits 0-4 = secs / 2
  110.         xor     ah,ah
  111.         mov     cl,5
  112.         shl     ax,cl           ;AX bits 5-10 = minute
  113.         or      ax,bx           ;AX = DOS file time
  114.         pLes    bx,DosTime
  115.         mov     FP[bx],ax       ;store DOS time in return variable
  116.         pop     dx              ;DX = DOS file date
  117.         pLes    bx,DosDate
  118.         mov     FP[bx],dx       ;store DOS date in return variable
  119.         ret                     ;back to caller
  120. UnixToDos ENDP
  121.  
  122. DosToUnix PROC, DosTime, DosDate
  123.         mov     bx,DosDate
  124.         mov     al,bh
  125.         xor     ah,ah
  126.         shr     ax,1            ;AX = DOS year
  127.         mov     ch,bl
  128.         and     ch,1fh
  129.         dec     ch              ;CH = DOS day (0 based)
  130.         and     bx,1e0h
  131.         mov     cl,5
  132.         shr     bx,cl
  133.         dec     bx              ;BX = DOS month (0 based)
  134.         mov     cl,al
  135.         add     cl,3
  136.         shr     cl,1
  137.         shr     cl,1            ;CL = # leap days due to past years
  138.         test    al,3
  139.         jnz     @F              ;jmp if this isn't a leap year
  140.         cmp     bl,1
  141.         jbe     @F              ;jmp if not past leap day yet
  142.         inc     cl              ;CL = total leap days
  143. @@:     add     cl,ch
  144.         xor     ch,ch           ;CX = day of month + all leap days
  145.         shl     bx,1            ;shift month for word table lookup
  146.         add     cx,DtoUtbl[bx]  ;CX = days this year + leap days
  147.         mov     dx,365
  148.         mul     dx              ;AX = days due to years
  149.         add     ax,cx           ;AX = total days since 1-1-80
  150.         mov     dx,43200        ;hour secs / 2 (avoid long multiply)
  151.         mul     dx              ;DX:AX = day secs since 1-1-80 / 2
  152.         shl     ax,1
  153.         rcl     dx,1            ;DX:AX = secs in days since 1-1-80
  154.         push    dx
  155.         push    ax              ;save partial result
  156.         mov     bx,DosTime
  157.         mov     al,bh
  158.         mov     cl,3
  159.         shr     al,cl           ;AL = hours
  160.         mov     ah,60
  161.         mul     ah              ;AX = mins due to hours
  162.         mov     dx,bx
  163.         and     dx,7e0h
  164.         mov     cl,5
  165.         shr     dx,cl           ;DX = minutes from DosTime
  166.         add     ax,dx           ;AX = total minutes
  167.         mov     cx,60
  168.         mul     cx              ;DX:AX = secs in hours and mins
  169.         and     bx,1fh
  170.         shl     bx,1            ;BX = secs field from DosTime
  171.         add     ax,bx
  172.         adc     dx,0            ;DX:AX = total secs from DosTime
  173.         pop     bx
  174.         pop     cx              ;CX:BX = total secs from DosDate
  175.         add     ax,bx
  176.         adc     dx,cx           ;DX:AX = tl secs from Dos timestamp
  177.         add     ax,LOCONST
  178.         adc     dx,HICONST      ;add secs from 1-1-70GMT to 1-1-80GMT
  179.         ret                     ;back to caller
  180. DosToUnix ENDP
  181.  
  182.         END
  183.  
  184.